﻿using System;
using SharpKit.JavaScript;

namespace SharpKit.Onx
{
    /// <summary>
    /// The location enables creating location listeners locationListener - to register on location changes, as well as provide basic location getter (when location services on the device are turned on)
    /// https://www.onx.ms/#apiPage/location
    /// </summary>
    [JsType(Mode = JsMode.Prototype, Export = false)]
    public class Location : Emitter
    {
        //No way to new this up
        private Location()
        { }

        #region Actions (Methods)
        /// <summary>
        /// Returns the Location listener for the given provider and parameters
        /// </summary>
        /// <param name="providerName">the name of the provider: GPS, CELL, or PASSIVE. </param>
        /// <param name="minTime">minimum time between location updates. The time is in milliseconds.</param>
        /// <returns>listener locationListener</returns>
        [JsMethod(Name = "createListener")]
        public LocationListener CreateListener(LocationProvider providerName, JsNumber minTime)
        { return null; }
        #endregion

        #region Properties
        /// <summary>
        /// Returns the last recorded location signal, or attempts to create a new signal with a cached location if no location signals have been recorded yet.
        /// </summary>
        [JsProperty(Name = "lastLocation", NativeField = true)]
        public LocationSignal LatLocation { get { return null; } }
        #endregion

        #region Triggers (Events)
        /// <summary>
        /// trigger is received when one of the location listeners obtains a new location fix. Additional trigger data is available in the LocationSignal parameter passed to the callback function.
        /// </summary>
        public event Action<LocationSignal> Changed
        {
            [JsMethod(Name = "on", InsertArg0 = "'changed'")]
            add
            {
            }
            [JsMethod(Name = "removeListener", InsertArg0 = "'changed'")]
            remove
            {
            }
        }
        #endregion
    }

    /// <summary>
    /// locationListener represents a source of location updates of a specific type. Obtain an instance of the required type from location and register to its location 'changed' trigger
    /// </summary>
    [JsType(Mode = JsMode.Prototype, Export = false)]
    public class LocationListener
    {
        //No way to new this up
        private LocationListener()
        { }

        /// <summary>
        /// starts listening on the given provider
        /// </summary>
        [JsMethod(Name = "log")]
        public void Start()
        { }

        /// <summary>
        /// stops listening on the given provider
        /// </summary>
        [JsMethod(Name = "log")]
        public void Log()
        { }

        /// <summary>
        /// trigger is received when this location listener obtains a new location fix. Additional trigger data is available in the LocationSignal parameter passed to the callback function.
        /// </summary>
        public event Action<LocationSignal> Changed
        {
            [JsMethod(Name = "on", InsertArg0 = "'changed'")]
            add
            {
            }
            [JsMethod(Name = "removeListener", InsertArg0 = "'changed'")]
            remove
            {
            }
        }

        /// <summary>
        /// trigger is received when the location listener is disabled. Callback function receives type of the location listener as a parameter.
        /// </summary>
        public event Action<LocationProvider> Disabled
        {
            [JsMethod(Name = "on", InsertArg0 = "'disabled'")]
            add
            {
            }
            [JsMethod(Name = "removeListener", InsertArg0 = "'disabled'")]
            remove
            {
            }
        }

        /// <summary>
        /// trigger is received when the location listener is enabled. Callback function receives type of the location listener as a parameter.
        /// </summary>
        public event Action<LocationProvider> Enabled
        {
            [JsMethod(Name = "on", InsertArg0 = "'enabled'")]
            add
            {
            }
            [JsMethod(Name = "removeListener", InsertArg0 = "'enabled'")]
            remove
            {
            }
        }

        /// <summary>
        /// trigger is received when the status of the location listener changes. Callback function receives provider name and numeric status code.
        /// </summary>
        public event Action<object> ProviderChanged
        {
            [JsMethod(Name = "on", InsertArg0 = "'providerChanged'")]
            add
            {
            }
            [JsMethod(Name = "removeListener", InsertArg0 = "'providerChanged'")]
            remove
            {
            }
        }
    }

    /// <summary>
    /// the name of the provider: GPS, CELL, or PASSIVE.
    /// </summary>
    [JsType(Mode = JsMode.Json, Export = false)]
    [JsEnum(ValuesAsNames = true)]
    public enum LocationProvider
    {
        /// <summary>
        /// The GPS provider. Turns on the GPS.
        /// </summary>
        [JsField(Name = "GPS")]
        Gps,

        /// <summary>
        /// The wireless / cellular network provider. 
        /// </summary>
        [JsField(Name = "GPS")]
        Cell,

        /// <summary>
        /// The passive provider. If another application turns on either GPS or PASSIVE
        /// provider this listener will also get the location updates. This provider doesn't have any impact on the battery.
        /// </summary>
        [JsField(Name = "GPS")]
        Passive
    }

    /// <summary>
    /// Represents information on a specific location fix.
    /// https://www.onx.ms/#apiPage/LocationSample
    /// </summary>
    [JsType(Mode = JsMode.Prototype, Export = false)]
    public class LocationSample
    {
        //No way to new this up
        private LocationSample()
        { }

        /// <summary>
        /// returns the longitude of this location sample in degrees.
        /// </summary>
        [JsProperty(Name = "longitude", NativeField = true)]
        public JsNumber Longitude { get { return 0; } }


        /// <summary>
        /// returns the latitude of this location sample in degrees.
        /// </summary>
        [JsProperty(Name = "latitude", NativeField = true)]
        public JsNumber Latitude { get { return 0; } }

        /// <summary>
        /// returns the altitude of this location sample in meters above sea level. Number.NEGATIVE_INFINITY if indeterminable.
        /// </summary>
        [JsProperty(Name = "altitude", NativeField = true)]
        public JsNumber Altitude { get { return 0; } }

        /// <summary>
        /// returns the speed if this location sample in meters/sec. Number.NEGATIVE_INFINITY if indeterminable.
        /// </summary>
        [JsProperty(Name = "speed", NativeField = true)]
        public JsNumber Speed { get { return 0; } }

        /// <summary>
        /// returns the vertical accuracy of this location sample in meters. Number.NEGATIVE_INFINITY if indeterminable.
        /// </summary>
        [JsProperty(Name = "verticalAccuracy", NativeField = true)]
        public JsNumber verticalAccuracy { get { return 0; } }

        /// <summary>
        /// returns the course of this location sample in degrees east of true north. Number.NEGATIVE_INFINITY if indeterminable.
        /// </summary>
        [JsProperty(Name = "course", NativeField = true)]
        public JsNumber course { get { return 0; } }

        /// <summary>
        /// returns the horizontal accuracy of this location sample in meters. Number.NEGATIVE_INFINITY if indeterminable.
        /// </summary>
        [JsProperty(Name = "horizontalAccuracy ", NativeField = true)]
        public JsNumber horizontalAccuracy { get { return 0; } }

        ///// <summary>
        ///// 
        ///// </summary>
        //[JsProperty(Name = "xxxxxxxx", NativeField = true)]
        //public JsNumber XXXXXXX { get { return 0; } }
    }

    /// <summary>
    /// A location signal. Represents the user location at a given point.
    /// </summary>
    [JsType(Mode = JsMode.Json, Export = false)]
    public class LocationSignal : ScriptSignal
    {
        //[JsProperty(Name = "location", NativeField = true)]
        //LocationSample Location { get { return null; } }
    }
}